<?php

namespace Biz\module\Classes\adm;

use Biz\model\activity\CouponConfig as mCouponConfig;
use Biz\model\GoodsBasicInfo;
use Biz\model\ShopBasicInfo as mShopBasicInfo;
use Biz\model\trade\Order as mOrder;
use Biz\model\trade\OrderGoods as mOrderGoods;
use Biz\model\trade\OrderPackage as mOrderPackage;
use Biz\model\trade\OrderRefund as mOrderRefund;
use Biz\model\trade\ShopCourier as mShopCourier;
use Biz\module\Classes\core\SearchListAbstract;
use Biz\pockets\constInterface\PayConfig;
use Biz\service\Group;
use Biz\service\redPacket\RedPacketsLog as sRedPacketsLog;
use Biz\service\trade\ShopCourier as sShopCourier;
use Biz\tools\Amount;
use Doraemon\model\Member as mMember;
use Doraemon\tools\HhzEnv;
use Medoo\Medoo;

class OrderSearch extends SearchListAbstract
{

    protected $join = []; //关联表
    protected $order = []; //字段排序
    protected $shopNames = [];//商家昵称
    private $isLike = false; //是否模糊

    private $maxOrderNums = 500;

    protected function buildSelect()
    {
        //查询order的字段
        $this->select = [
            'o.order_no',
            'o.order_parent_no',
            'o.shop_id',
            'o.uid',
            'o.addtime',
            'o.goods_amount',
            'o.s_coupon_vid',
            'o.s_coupon_amount',
            'o.shipping_amount',
            'o.activity_allowance',
            'o.integral_amount',
            'o.coupon_amount',
            'o.refunding_status',
            'o.status',
            'o.consignee_name',
            'o.consignee_phone',
            'o.meal_id',
            'o.meal_amount',
            'o.cancel_reason',
            'o.cancel_type',
            'o.order_type',
            'o.refund_amount',
            'o.refunded_amount',
            'o.pay_amount',
            'o.pay_way',
            'o.from_source',
        ];
    }

    protected function buildJoin($join)
    {
        $this->join = $join;
    }

    protected function buildOrder($order)
    {
        $this->order = $order;
    }


    protected function buildWhere()
    {
        if (!empty($this->params['disable_by_category'])) {
            $disableList = explode(',', $this->params['disable_by_category']);
            $this->params = array_filter($this->params, function ($k) use ($disableList) {
                if (in_array($k, $disableList)) {
                    return false;
                }
                return true;
            }, ARRAY_FILTER_USE_KEY);

        }
        if (!empty($this->params['status'])) {
            $this->where['o.status'] = $this->params['status'];
        }

        if (!empty($this->params['order_no'])) {
            $this->where['o.order_no #1'] = htmlspecialchars($this->params['order_no']);
        }

        if (!empty($this->params['consignee_phone'])) {
            $this->where['o.consignee_phone'] = htmlspecialchars($this->params['consignee_phone']);
        }

        if (!empty($this->params['consignee_name'])) {
            $this->where['o.consignee_name[~]'] = htmlspecialchars($this->params['consignee_name']);
        }

        if (!empty($this->params['title'])) {
            $this->buildJoin(['[>]order_goods(og)' => ['o.order_no' => 'order_no']]);
            $this->where['og.title[~]'] = htmlspecialchars($this->params['title']);
        }
        if (!empty($this->params['promo_type'])) {
            $this->buildJoin(['[>]order_goods(og)' => ['o.order_no' => 'order_no']]);
            $this->where['og.promo_type'] = $this->params['promo_type'];
            if (!empty($this->params['promo_id'])) {
                $this->where['og.promo_id'] = $this->params['promo_id'];
            }
        }

        if (isset($this->params['category_id']) && $this->params['category_id'] > 0) {
            $this->buildJoin(['[>]order_goods(og)' => ['o.order_no' => 'order_no']]);
            $this->where['og.category_id'] = $this->params['category_id'];
        }


        if (isset($this->params['second_category_id']) && $this->params['second_category_id'] > 0) {
            $this->buildJoin(['[>]order_goods(og)' => ['o.order_no' => 'order_no']]);
            $this->where['og.second_category_id'] = $this->params['second_category_id'];
        }

        if (empty($this->params['time_type'])) {
            $this->buildOrder(['ORDER' => ['o.addtime' => 'DESC']]);
        } else {
            switch ($this->params['time_type']) {
                case 1: //下单时间
                    if (!empty($this->params['start_time'])) {
                        $this->where['o.addtime[>]'] = date('Y-m-d H:i:s', strtotime($this->params['start_time']));
                    }
                    if (!empty($this->params['end_time'])) {
                        $this->where['o.addtime[<]'] = date('Y-m-d H:i:s', strtotime($this->params['end_time']) + 86400);
                    }
                    $this->buildOrder(['ORDER' => ['o.addtime' => 'DESC']]);
                    break;
                case 2: //付款时间
                    if (!empty($this->params['start_time'])) {
                        $this->where['o.pay_time[>]'] = date('Y-m-d H:i:s', strtotime($this->params['start_time']));
                    }
                    if (!empty($this->params['end_time'])) {
                        $this->where['o.pay_time[<]'] = date('Y-m-d H:i:s', strtotime($this->params['end_time']) + 86400);
                    }
                    $this->buildOrder(['ORDER' => ['o.pay_time' => 'DESC']]);
                    break;
                case 3: //确认收货时间
                    if (!empty($this->params['start_time'])) {
                        $this->where['o.confirm_time[>]'] = date('Y-m-d H:i:s', strtotime($this->params['start_time']));
                    }
                    if (!empty($this->params['end_time'])) {
                        $this->where['o.confirm_time[<]'] = date('Y-m-d H:i:s', strtotime($this->params['end_time']) + 86400);
                    }
                    $this->buildOrder(['ORDER' => ['o.confirm_time' => 'DESC']]);
                    break;
                default:
                    break;
            }
        }

        if (!empty($this->params['field1'])) {

            if (!empty($this->params['keyword1'])) {
                if ($this->params['field1'] == 'shop_id') {
                    $this->where['o.' . $this->params['field1']] = $this->params['keyword1'];
                } else if ($this->params['field1'] == 'shop_name') {
                    $shopList = mShopBasicInfo::selectFieldsByFilter([
                        'shop_id',
                        'name'
                    ], ['name[~]' => $this->params['keyword1']]);
                    $shopIds = array_column($shopList, 'shop_id');
                    $this->shopNames = array_column($shopList, 'name', 'shop_id');
                    $this->where['o.shop_id'] = $shopIds;
                    $this->isLike = true;
                }
            }
        }
        if (!empty($this->params['field2'])) {

            if (!empty($this->params['keyword2'])) {
                if ($this->params['field2'] == 'uid') {
                    $this->where['o.uid'] = $this->params['keyword2'];
                } else if ($this->params['field2'] == 'user_name') {
                    $uid = mMember::getUidByNick($this->params['keyword2']);

                    if ($uid > 0) {
                        $this->where['o.uid'] = $uid;
                    } else {
                        $this->where['o.uid'] = false;
                    }
                }
            }
        }

        if (!empty($this->params['field3'])) {

            if (!empty($this->params['keyword3'])) {
                if ($this->params['field3'] == 'goods_id') {
                    $orderNos = mOrderGoods::getOrderNosByGoodsId($this->params['keyword3']);
                    if ($orderNos) {
                        $this->where['o.order_no #2'] = $orderNos;
                    } else {
                        $this->where['o.order_no #2'] = false;
                    }
                } else if ($this->params['field3'] == 'sku_id') {
                    $orderNos = mOrderGoods::getOrderNosBySkuId($this->params['keyword3']);
                    if ($orderNos) {
                        $this->where['o.order_no #2'] = $orderNos;
                    } else {
                        $this->where['o.order_no #2'] = false;
                    }
                }
            }
        }

        if (!empty($this->params['only_refund'])) {
            $this->where['o.refunding_status'] = mOrder::REFUNDING_STATUS_PROCESS;
            $this->buildJoin(['[<]order_refund(or)' => ['o.order_no' => 'order_no']]);
            $this->where['or.status[!]'] = [
                mOrderRefund::STATUS_REJECT,
                mOrderRefund::STATUS_CANCEL,
                mOrderRefund::STATUS_RETURN_GOODS_CANCEL
            ];
        }

        if (!empty($this->params['custom_pay_way_refund'])) {
            $this->where['o.refunding_status'] = mOrder::REFUNDING_STATUS_PROCESS;
            $this->where['o.pay_way'] = PayConfig::_PAY_WAYS_CUSTOMIZE_PAY_WAY;
            $this->buildJoin(['[<]order_refund(or)' => ['o.order_no' => 'order_no']]);
            $this->where['or.status'] = [
                mOrderRefund::STATUS_NORMAL,
                mOrderRefund::STATUS_WAIT_CONFIRM_RECEIPT,
                mOrderRefund::STATUS_REFUNDING
            ];
        }

        if (!empty($this->params['exclude_test_shop'])) {
            if ($this->params['exclude_test_shop'] == 1) {
                $this->where['o.shop_id[!]'] = GoodsBasicInfo::$testShopIds;
            }
        }

        if (!empty($this->params['coupon_id'])) {
            $couponInfo = mCouponConfig::getCouponInfo($this->params['coupon_id']);

            if ($couponInfo['assume'] == mCouponConfig::COUPON_ASSUME_HHZ) {
                $this->where['o.coupon_id'] = $this->params['coupon_id'];
            } else {
                $this->where['o.s_coupon_id'] = $this->params['coupon_id'];
            }
        }

        if (isset($this->params['from_source']) && $this->params['from_source'] >= 0) {
            $this->where['o.from_source'] = $this->params['from_source'];
        }

        if (!empty($this->params['express_no'])) {
            $orderNos1 = mOrder::select(['order_no'], ['express_no' => $this->params['express_no']]);
            $orderNos2 = mOrderPackage::select(['order_no'], ['express_no' => $this->params['express_no']]);

            $this->where['o.order_no #3'] = array_unique(array_column(array_merge($orderNos1, $orderNos2), 'order_no'));

        }
    }

    public function getCount()
    {
        if ($this->join) {
            $rows = mOrder::get($this->join, ['counts' => Medoo::raw('COUNT(DISTINCT(<o.order_no>))')], $this->where);
            $count = $rows['counts'];
        } else {
            $count = mOrder::count($this->where);
        }
        return $count;
    }

    public function getList()
    {
        if ($this->order) {
            $this->where = $this->where + $this->order;
        }
        if ($this->join) {
            $this->where['GROUP'] = 'o.order_no';
            $this->select['counts'] = Medoo::raw('COUNT(<o.order_no>)'); //方便查看一个符合模糊title订单下的goods-sku的个数
            $orders = mOrder::select($this->join, $this->select, array_merge($this->where, ['LIMIT' => $this->limit]));
        } else {
            $orders = mOrder::select($this->select, array_merge($this->where, ['LIMIT' => $this->limit]));
        }

        return $orders;
    }

    public function orderList()
    {
        $goodsList = [];
        $count = $this->getCount();
        $orders = $this->getList();
        //var_dump(mOrder::log());die;
        $orderNos = array_column($orders, 'order_no');

        if ($orderNos) {
            if ($this->isLike == false) {
                $shopList = mShopBasicInfo::selectFieldsByFilter([
                    'shop_id',
                    'name'
                ], ['shop_id' => array_column($orders, 'shop_id')]);
                $this->shopNames = array_column($shopList, 'name', 'shop_id');
            }
            $orderGoodsList = mOrderGoods::getFieldsByOrderNo($orderNos, [
                'sku_id',
                'pay_amount',
                'goods_id',
                'cover_img',
                'title',
                'sell_price',
                'buy_price',
                's_coupon_amount',
                'buy_num',
                'sku_desc',
                'order_no',
                'meal_amount'
            ]);
            $shopDomain = HhzEnv::detectShopDomain();
            foreach ($orderGoodsList as $key => $orderGoods) {
                $orderGoods['cover_img'] = $orderGoods['cover_img_thumb_url'];
                $orderGoods['goods_h5_url'] = $shopDomain . 'h5_goodsDetail/?goods_id=' . $orderGoods['goods_id'];
                $goodsList[$orderGoods['order_no']][] = $orderGoods;
            }
            //拼团信息的组装
            $pintuanList = Group::getOrderGroupStatus($orderNos);

            //是否有正在进行，或者已成功的退款
            $refundIngList = mOrderRefund::getRefundedOrRefundingList($orderNos, '', 'order_no');


            //包裹列表
            $orderPackageList = mOrderPackage::getExpressInfoList($orderNos);

            //var_dump(mOrderGoods::sqlLogs());die;
            foreach ($orders as &$orderInfo) {
                $orderInfo['shop_name'] = isset($this->shopNames[$orderInfo['shop_id']]) ? $this->shopNames[$orderInfo['shop_id']] : '';
                $orderInfo['user_name'] = empty($nick = mMember::getUser($orderInfo['uid'])['nick']) ? '' : $nick;

                $orderInfo['courier_id'] = sShopCourier::getCourierIdByCourierName($orderPackageList[$orderInfo['order_no']][0]['express_company']);

                if ($orderInfo['courier_id'] == mShopCourier::SELF_LIFTING_ID && $orderInfo['status'] == mOrder::STATUS_WAIT_SEND) {
                    $orderInfo['status_desc'] = '待确认';
                } else {
                    $orderInfo['status_desc'] = isset (mOrder::$statusAdmDesc[$orderInfo['status']]) ? mOrder::$statusAdmDesc[$orderInfo['status']] : '';
                }

                $orderInfo['cancel_reason_desc'] = $orderInfo['cancel_reason'] > 0 ? mOrder::$cancelReasonDesc[$orderInfo['cancel_reason']] : '';
                $orderInfo['order_amount'] = Amount::format($orderInfo['goods_amount'] + $orderInfo['shipping_amount']);
                $orderInfo['cancel_type_desc'] = $orderInfo['cancel_type'] > 0 ? mOrder::$cancelTypeDesc[$orderInfo['cancel_type']] : '';
                $orderInfo['goods'] = $goodsList[$orderInfo['order_no']];

                $orderInfo['has_refund'] = isset($refundIngList[$orderInfo['order_no']]) ? true : false;

                $orderInfo['pintuan'] = isset($pintuanList[$orderInfo['order_no']]) ? $pintuanList[$orderInfo['order_no']] : [];

                $orderNo[] = $orderInfo['order_no'];
            }

            $allPayAmount = '';
            if ($count < $this->maxOrderNums) {
                if ($this->join) {
                    unset($this->where['GROUP']);
                    $allPayAmount = mOrder::select($this->join, ["all_pay_amount" => Medoo::raw("SUM(<o.pay_amount> + <o.integral_amount> + <o.coupon_amount>+<o.activity_allowance>)")], $this->where);
                } else {
                    $allPayAmount = mOrder::select(["all_pay_amount" => Medoo::raw("SUM(<o.pay_amount> + <o.integral_amount> + <o.coupon_amount>+<o.activity_allowance>)")], $this->where);
                }
                $allPayAmount = $allPayAmount[0]['all_pay_amount'];
            }

            //是否使用红包
            if (!empty($orderNo)) {
                $red_packet = sRedPacketsLog::getList($orderNo);
                $orders = array_map(function ($_item) use ($red_packet) {
                    if (isset($red_packet[$_item['order_no']])) {
                        $_item['red_packet'] = $red_packet[$_item['order_no']]['packet_amount'];
                    } else {
                        $_item['red_packet'] = 0;
                    }
                    return $_item;
                }, $orders);
            }
        }

        return [
            'list' => $orders,
            'count' => $count ?: 0,
            'total_pay_amount' => $allPayAmount ?: 0
        ];
    }

    protected function allCount()
    {
        $counts = [
            mOrder::STATUS_NORMAL => 0,
            //待付款
            mOrder::STATUS_WAIT_SEND => 0,
            //待发货
            mOrder::STATUS_SEND_OUT => 0,
            //待收货
            mOrder::STATUS_SUCCESS => 0,
            //交易成功
            mOrder::STATUS_CLOSE => 0
            //交易关闭
        ];
        $allCount = mOrder::select([
            'counts' => Medoo::raw('COUNT(<o.order_no>)'),
            'o.status'
        ], [
            'GROUP' => 'o.status',
            'o.shop_id' => $this->params['shop_id']
        ]);
        array_walk($allCount, function ($v) use (&$counts) {
            if (key_exists($v['status'], $counts)) {
                $counts[$v['status']] = $v['counts'];
            }
        });
        return $counts;
    }

    public function getOrderIds($params, $limit)
    {
        var_dump($params, 111);die;
    }
}